enum ו-set הם שני סוגי נתונים מאוד מיוחדים ב-mysql ותכף תדע מה כל כך מעניין בהם. לדגומה השדה מסוג "מין". שדה כזה יכול להכיל רק ערכים קבועים "זכר" ו"נקבה". מסתבר שאפשר להגביל את הערכים האלה בכוחות המסד עצמו. בוא תראה איך.
Enum
הוא הפשוט מבין השניים. שדה מסוג Enum הוא שדה טקסט (מחרוזת) עם רשימת ערכים קבועים.
מעולה כדי לשמור נתונים כמו מין, מצב משפחתי או כל דבר שנבחר מרשימת ערכים קבוע.
אני משתמש בזה בעמוד "שפר את האתר" עבור סוג ההצעה, רעיון, בקשה וגם עבור המצב התקבל, טופל, נדחה וכו'..
אופן הפעולה הפנימי שלו הוא כזה, שלכל אופציה מוגדר מספר
התקבל = 1 , בוצע = 2 , נדחה = 3
ככה שהמקום שהשדה הזה טופס הוא יחסית קטן.
Set
set דומה מאוד ל enum אבל הרבה יותר מעניין.
הוא מאפשר לבחור בבת אחת כמה ערכים מתוך רשימה קבוע.
לדגומה, מתאים לשמירת הרשאות משתמשים.
היצירה שלו זהה לזו של enum:
טבלה לדוגמה
CREATE TABLE IF NOT EXISTS `setest` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`permissions` set('read','write','edit','delete','upload') NOT NULL,
PRIMARY KEY (`userid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
`userid` int(11) NOT NULL AUTO_INCREMENT,
`permissions` set('read','write','edit','delete','upload') NOT NULL,
PRIMARY KEY (`userid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
עמודה "הרשאות" תשמור עבור כל משתמש את הרשאות המשתמש. המשתמש יכול
[*] "לקרוא" כתבות בבלוג
[*] "לכתוב" בבלוג
[*] "לערוך כתבות" שאת זה יוכלו רק מפקחים
[*] "למחוק כתבות" שאת זה יוכלו רק מנהלים
[*] "להעלות תמונות" שאת זה יכולו רק משתמשים עם הרשאות מיוחדות
כדי לאפשר למשתמש רק לקרוא כתבות ניתן לו הרשאות קריאה בלבד:
INSERT INTO `setest` (`userid`, `permissions`) VALUES ('3', 'read');
כדי לאפשר למשתמש לקרוא ולכתוב ניתן הרשאות קריאה וכתיבה:
INSERT INTO `setest` (`userid`, `permissions`)
VALUES ('4', 'read,write');
VALUES ('4', 'read,write');
לקרוא, לכתוב ולהעלות תמונות:
INSERT INTO `setest` (`userid`, `permissions`)
VALUES ('5', 'read,write,upload');
VALUES ('5', 'read,write,upload');
לבחור את כל המשתמשים שיכולים לקרוא כתבות:
SELECT * FROM setest WHERE FIND_IN_SET('read',premissions)>0;
בדיקת הרשאות אם php - האם הקוד יודע?
ומה קורה אחרי ששלפנו את השורה מהמסד, איך בקוד נדע אם המשתמש רשאי לעשות משהו או לא?
תוצאת השליפה שנקבל תכיל רשימה מלאה של כל ההרשאות שהמשתמש יכול לעשות ותראה ככה
Array ( [userid] => 5 [permissions] => read,write,upload )
קוד הבדיקה:
if( strpos($user['permissions'], "read") !== false )
{
echo 'user can read';
}
{
echo 'user can read';
}
אופן הפעולה הפנימי של SET הוא כזה, שלכל אופציה מוגדר מספר
רשאי לקרוא דואר = 1 ,
רשאי לשלוח דואר = 2 ,
רשאי לקרוא פורום = 4 ,
רשאי לכתוב בפורום = 8 ,
רשאי למחוק הודעות מהפורום = 16
כל המספורים הם חזקות של 2.
דבר זה מאפשר לבחור כמה ערכים בבת אחת.
אם אנחנו רוצים שהבן אדם יוכל גם לשלוח דואר וגם לקרוא דואר ניתן לו את הערך 3
1 & 2 = 3
אם נרצה לאפשר לו רק לקרוא הודעות בפורום והודעות דואר ניתן לו את הערך
1 & 4 = 5
רק לקרוא , למחוק הודעות מהפורום וגם לקרוא דואר: (בלי לענות בפורום או בדואר)
1 & 4 & 16 = 21
את חישוב הביתים מנוע המסד עושה במקומנו ואנחנו רק עובדים עם ערכים טקסטואליים.
--------
עוד שני שדות במסד עכשיו עומדים לשירותך ותוכל לבחור את סוג השדה הטוב ביותר עבור הבעיה שאתה פותר. השתמש במסד בחוכמה :)
תגובות לכתבה:
אהבתי.. תודה רבה אלכס!
תודה!
נחמד מאוד. :)
הסבר מצוין על ההבדלים בין השניים.
הסבר נוסף למה כל המספרים הם כפולות של 2 היא האופן שבו הנתונים נשמרים במסד, בצורה בינארית. צורה בינארית מאפשרת לנו "לחבר" כמה נתונים כך שבקלות ניתן "להפריד" אותם לרכיבים המקוריים, בדיוק באותה צורה שבה עובד מנגנון ההרשאות בלינוקס או מנגנון פתיחת קבצים ב- PHP.
רק לתיקון, יותר מדויק להגיד שאלה חזקות של 2, לא כפולות של 2.
צודק, תוקן, תודה :)
חשוב גם לציין שה-ORDER BY לא ממיין לפי המיקום האלפביתי של הערכים במקרה של enum.
הוא ממיין לפי המיקום של הערך ברשימה (אני מאמין שככה זה גם עם set אבל לא ניסיתי).
ככה שאם נגדיר enum עם הערכים true ו-false (כך שברשימת הערכים true לפני false), אז כשנעשה order by על העמודה הזו - true יבוא לפני false. אפילו שלפי מיון אלפביתי false הוא לפני true (האות f היא לפני t).
שימו לב לזה,
העניין הזה בזבז לי כמעט חצי שעה. -.-
הבעיה היחידה בקטע של ההרשאות היא שאם יש לכם מערכת גדולה - זה תופס המון מקום, ואז אין ברירה אלא לחלק את זה למספר קטגוריות של הרשאות, ולכל קטגוריה יש עמודה אחרת, לא? אלא אם כן אני טועה או שיש שיטה אחרת?
* (אם יש לכם מערכת גדולה, כך שיש המון סוגים של הרשאות, אפילו 70.)
מאמר מצויין, תודה רבה!
@LighTo273
SET יכול לקבל עד 64 ערכים שונים (אני מדבר על mysql). :)
כעיקרון כשמדברים על הרשאות עם SET מדברים על הרשאות גלובליות פחות או יותר, כמו קריאה של מדריכים, כתיבת מדריכים, עריכת מדריכים, מחיקת מדריכים, קריאת פוסטים בפורום, כתיבת פוסטים בפורום, עריכת פוסטים בפורום, מחיקת פוסטים מהפורום, שינוי הרשאות למשתמשים אחרים, עריכת פרטים של משתמשים אחרים, גישה לפאנל הניהול וכו'.
אם אתה רוצה להוסיף אופציות יותר ספציפיות, כמו "לא יכול לצפות מדריך מספר 8", תצטרך להוסיף את זה בצורה אחרת כמובן. אבל לרוב לא צריכים את זה. לרוב המשתמשים מתחלקים לקבוצות ברורות עם הרשאות משותפות ומוסיפים עוד עמודת SET אם רוצים לשנות הרשאות כלליות (כמו שציינתי למעלה) למשתמשים ספיציפיים.
אני מדבר על השיטה הכללית, ולא ספציפית על SET ב-MySQL.
כשאני אומר מערכת גדולה, אני מדבר על מערכת ענקית, שיש בה הרבה מאוד דברים, כך שבסופו של דבר מספר ההרשאות הכלליות השונות עולות על 64.
אגב, אם למשל יש לי כמה פורומים, לכל אחד מהם אני אעשה מספר הרשאות שונות בשיטה הזאת. אני לא אתחיל לתכנן עוד מערכת הרשאות אחרת, מה שגם אומר שצריך עוד עמודה בטבלת המשתמשים. (זה בקשר לאופציות יותר ספציפיות שאמרת.)
ב-set אתה לא מכניס את "יכול לצפות בפורום 8", אתה מכניס "יכול לצפות בפורומים". זה נקרא "הרשאות גלובליות" יותר.
כמו שאמרתי, אני פשוט מכניס לעמודה מספר, ואז עובד עליו עם אופרטורי Bitwise, בלי שימוש ב-SET. בכל מקרה, אז איך אני אמור לעשות את זה בלי לסבך את המערכת שלי יותר ויותר?